package org.example.gradleauth.service.impl;

import gradle.common.core.constants.CommonConstant;
import gradle.common.core.mode.entity.SystemPermissions;
import gradle.common.core.mode.entity.SystemUser;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.gradleauth.feigns.service.GradleAdminFeignClient;
import org.example.gradleauth.model.entity.StaffUserDetails;
import org.example.gradleauth.util.PermissionsUtil;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 用户提交用户名和密码
 ↓
 构造 UsernamePasswordAuthenticationToken
 ↓
 调用 AuthenticationManager.authenticate()
 ↓
 ProviderManager 遍历 AuthenticationProvider
 ↓
 DaoAuthenticationProvider 调用 UserDetailsService.loadUserByUsername()
 ↓
 用 PasswordEncoder 比对密码
 ↓
 认证成功 → 返回 Authentication 对象
 ↓
 SecurityContextHolder 存储 Authentication

 https://docs.qq.com/aio/DRUJKc2RvV1pQVGF0?AIGenerate=1&openAiAssistant=1


 * @author 1141193930@qq.com
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

	@Resource
	private GradleAdminFeignClient gradleAdminFeignClient;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		//query user
		SystemUser customUser = gradleAdminFeignClient.loadUserByUsername(username);
		//判断用户是否存在
		if (Objects.isNull(customUser)) {
			//此处会被替换成 bad credentials exception
			//详情请参考：org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.hideUserNotFoundExceptions
			//可以在org.example.gradleauth.security.SecurityConfiguration中进行开启
			throw new UsernameNotFoundException("账号不存在！");
		}
		//判断用户是否可用
		if (Objects.equals(customUser.getEnable(), CommonConstant.DISABLE)) {
			throw new DisabledException("账户已被禁用！");
		}
		//获取所有权限列表 考虑后续的redis缓存
		List<SystemPermissions> permissionsAll = gradleAdminFeignClient.queryPermAll();
		//获取当前用户权限
		List<Long> permIdList = gradleAdminFeignClient.queryIdListPermByUserId(customUser.getId());
		//计算当前拥有权限
		List<GrantedAuthority> grantedAuthoritys = PermissionsUtil.getAllInheritedPermissions(permissionsAll,  new HashSet<>(permIdList))
				.stream()
				.map(permissions -> new SimpleGrantedAuthority(permissions.getPermCode()))
				.collect(Collectors.toList());

		return new StaffUserDetails(customUser, grantedAuthoritys);
	}



}
